/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2023-04-09     Administrator       the first version
 */

#include <rtthread.h>
#include <rtdevice.h>
#include "dev_sensors.h"
#include "drv_soft_i2c.h"
#include "user.h"

#define DBG_TAG "drv.sensors"
#define DBG_LVL DBG_ERROR
#include <rtdbg.h>



#define SENSIRS_I2C_BUS_NAME          "i2c2"  /* 传感器连接的I2C总线设备名称 */




#define SHT20_TEMP_COVER(x)  (175.72f * x / 65536 - 46.85f) //温度计算公式
#define SHT20_HUMI_COVER(x)  (125.00f * x / 65536 -   6.0f) //湿度计算公式

static struct rt_i2c_bus_device *i2c_bus = RT_NULL;     /* I2C总线设备句柄  */

rt_err_t i2c_bus_init(void)
{
    int find_count = 10;
    while(i2c_bus == RT_NULL)
    {
        i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(SENSIRS_I2C_BUS_NAME);
        LOG_D("finding device %s..\n",SENSIRS_I2C_BUS_NAME);
        rt_thread_mdelay(500);
        if (!(find_count--)) {
            LOG_E("finding device %s ..\n",SENSIRS_I2C_BUS_NAME);
            return RT_ERROR;
        }
    }
    LOG_D("finding device %s succeeful.\n",SENSIRS_I2C_BUS_NAME);
    return RT_EOK;
}


float sht20_readdata(uint8_t mode)
{
    uint16_t data = 0;
    rt_uint8_t recdata[3];

    rt_i2c_master_send(i2c_bus, SHT20_ADDR, RT_I2C_WR, &mode, 1 );
    rt_thread_mdelay(400);
    rt_i2c_master_recv(i2c_bus, SHT20_ADDR, RT_I2C_RD, recdata, sizeof(recdata));

    data = (recdata[0] << 8 ) | recdata[1];

    if (mode == TRIGGER_TEMP_MEASURE_NOHOLD) {
        data = (float)SHT20_TEMP_COVER(data);
    }
    else if (mode == TRIGGER_HUMD_MEASURE_NOHOLD) {
        data = (float)SHT20_HUMI_COVER(data);
    }
    return data;
}

void read_temp_humi(float *cur_temp, float *cur_humi)
{
    *cur_temp = sht20_readdata(TRIGGER_TEMP_MEASURE_NOHOLD);
    *cur_humi = sht20_readdata(TRIGGER_HUMD_MEASURE_NOHOLD);
    LOG_D("TEMP : %.1f C HUMI : %.1f % .\n", *cur_temp, *cur_humi);
}


unsigned char sht20_readUserRegister(void)
{
    unsigned char userRegister = READ_USER_REG;
    const unsigned char ret = userRegister;

    rt_i2c_master_send(i2c_bus, SHT20_ADDR, RT_I2C_WR, &ret, 1 );
    rt_thread_mdelay(1);
    userRegister = 0;
    rt_i2c_master_send(i2c_bus, SHT20_ADDR, RT_I2C_RD, &userRegister, 1 );
    return userRegister;
}

void sht20_writeUserRegister(char data)
{
    const unsigned char userRegister[] = {WRITE_USER_REG, data};
    rt_i2c_master_send(i2c_bus, SHT20_ADDR, RT_I2C_WR, userRegister, 2 );
}

void sht20_check(void)
{
    char reg = sht20_readUserRegister();
    reg = reg;
    LOG_I("End of battery: 0x02x% \n.", reg & USER_REGISTER_END_OF_BATTERY);
    LOG_I("Heater enabled: 0x02x% \n.", reg & USER_REGISTER_HEATER_ENABLED);
    LOG_I("Disable OTP reload: 0x02x \n.%", reg & USER_REGISTER_DISABLE_OTP_RELOAD);
}

rt_err_t dev_sgp30_init(void)
{
    uint8_t init_cmd[]={0x20,0x03};

    if (rt_i2c_master_send(i2c_bus,  SGP30_ADDR, RT_I2C_WR,
                           init_cmd, sizeof(init_cmd)) !=  sizeof(init_cmd)) {
        LOG_E("spg30 init failed!\n");
        return RT_ERROR;
    }
    else
    {
        LOG_D("spg30 init succeed!\n");
        return RT_EOK;
    }
}

rt_err_t dev_sgp30_read(uint16_t* CO2_Value, uint16_t* TVOC_Vlaue)
{
    uint8_t recdata[6] = {0};
    uint8_t read_cmd[]={0x20,0x08};

    if (rt_i2c_master_send(i2c_bus, SGP30_ADDR, RT_I2C_WR, read_cmd, sizeof(read_cmd)) !=  sizeof(read_cmd)) {
        LOG_E("sgp30 send failed...\n");
        return RT_ERROR;
    }

    rt_thread_mdelay(100);

    if (rt_i2c_master_recv(i2c_bus, SGP30_ADDR, RT_I2C_RD, recdata, sizeof(recdata)) != sizeof(recdata)) {
        LOG_E("sgp30 read failed...\n");
        return RT_ERROR;
    }

    *CO2_Value  = (recdata[0] << 8) | recdata[1];
    *TVOC_Vlaue = (recdata[3] << 8) | recdata[4];

    if (*CO2_Value == 400 && *TVOC_Vlaue == 0){
        LOG_W("sgp30 initing...\n");
        return RT_EBUSY;
    }else{
        LOG_I("CO2 : %d  TVOC : %d. \n",*CO2_Value, *TVOC_Vlaue);
        return RT_EOK;
    }
}




rt_adc_device_t adc_dev = NULL;

void dev_adc_channel_init(void)
{
    /* 查找设备 */
    adc_dev = (rt_adc_device_t)rt_device_find(ADC_DEV_NAME);
    if (adc_dev == RT_NULL)
    {
        rt_kprintf("adc sample run failed! can't find %s device!\n", ADC_DEV_NAME);
        return;
    }
    /* 使能设备 */
    rt_adc_enable(adc_dev, ADC_MQ137_CHANNEL);
}

/* 转换为对应电压值 */
void adc_read_channels(float* value, uint32_t channel)
{
    uint32_t ret = rt_adc_read(adc_dev, channel);
    *value =  ret * REFER_VOLTAGE / CONVERT_BITS;
}
/* 原始值 */
int adc_read_channels_src( uint32_t channel)
{
    return rt_adc_read(adc_dev, channel);
}

/* 关闭通道 */
rt_err_t adc_close_channel(uint32_t channel)
{
    return rt_adc_disable(adc_dev, channel);
}


#define PM25_MAX_ADCV 3.5229f
#define PM25_MIN_ADCV 0.5846f
#define GP2Y10_LED  37
int get_gp2y10_value(void)
{
    int ret;
    float retf;


    rt_pin_write(GP2Y10_LED, 1);
    rt_hw_us_delay(280);
    ret = rt_adc_read(adc_dev, ADC_GP2Y10_CHANNEL);
    rt_hw_us_delay(40);
    rt_pin_write(GP2Y10_LED, 0);
    retf = ret * 3.3f / 4095;
    if (retf > PM25_MAX_ADCV) {
        retf = PM25_MAX_ADCV;
    }
    if (retf > PM25_MIN_ADCV) {
        retf = PM25_MIN_ADCV;
    }
    return (int)(retf * 0.1686f - 0.09856f);
}


















